import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import java.lang.Thread;

class ScreenCanvas extends Canvas implements Runnable {
	private Thread processorThread;
	private Clock clock;
	private Senku senku;
	
	private int startX=0, startY=0;
	private int endX=0, endY=0;
	
	private int cursorX = 0;
	private int cursorY = 0;
	
	int w = getWidth();
	int h = getHeight();
	int cellWidth = w/7;
	int cellHeight = h/7;
	
	// coin dimensions
	int coinW;
	int coinH;
	
	boolean pressReleased = true;
	
	private TouchSenku father;
	
	ScreenCanvas(TouchSenku father)
	{
		this.father = father;
		this.clock = new Clock();
		this.senku = new Senku(this.father);
		this.initGame();
		processorThread = new Thread(this);
        processorThread.start();
	}
	
	public void run()
	{
		while(true)
		{
			try
			{
				repaint();
				processorThread.sleep(1000L);
			}
			catch(InterruptedException ie)
			{}
		}
	}
	
	protected void paint (Graphics g)
	{
		w = getWidth();
		h = getHeight();
		cellWidth = w/7;
		cellHeight = h/7;
		
		coinW = cellWidth-4;
		coinH = cellHeight-4;
		
		g.setGrayScale (255);
		g.fillRect(0,0,w,h);
		drawBoard(g);
		if(!this.pressReleased)
		{
			g.setGrayScale(0);
			g.fillArc(this.endX-cellWidth/2, this.endY-cellHeight/2, cellWidth-6, cellHeight-6,0, 360);
		}
		
		// draw selection
		g.setColor(0x00FF00);
		g.drawRect(cursorX*cellWidth+2, cursorY*cellHeight+2, cellWidth-4, cellHeight-4);
		
		drawClock(g);
	}
	
	public void pointerPressed (int x, int y) {
		if(this.senku.selectCoin(x/cellWidth, y/cellHeight))
		{
			this.pressReleased = false;
			this.senku.moveCoin(x/cellWidth, y/cellHeight);
			this.endX = x;
			this.endY = y;
			repaint();
		}
	}
	
	public void pointerReleased (int x, int y) {
		if(!this.pressReleased)
		{
			this.senku.moveCoinTo(x/cellWidth, y/cellHeight);
			if(this.senku.checkGameOver())
			{
				this.clock.stop();
				this.father.gameOver(this.senku.getMode(), this.senku.leftCoins());
			}
		}
		this.pressReleased = true;
		serviceRepaints();
		repaint();
	}
	
	public void pointerDragged(int x, int y)
	{
		if(!this.pressReleased)
		{
			this.endX = x;
			this.endY = y;
			
			repaint();
		}
	}
	
	protected void drawBoard(Graphics g)
	{
		
		for(int i=0; i<7; i++)
		{
			for(int j=0; j<7; j++)
			{
				int cellValue = this.senku.getField(i, j);
				int selected = cellValue/10;
				cellValue %=10;
				if(cellValue < 3)
				{
					drawCell(g, i, j);
					if(cellValue == 2)
						g.setGrayScale(180);
					else
						g.setGrayScale(0);
					g.drawRect(i*cellWidth, j*cellHeight, cellWidth, cellHeight);
					if(cellValue == 1 || cellValue == 2)
						drawCoin(g, i, j);
					if(selected == 1)
						drawSelected(g, i, j);
				}
				
			}
		}
	}
	
	/**
	 * drawCell
	 *
	 * @int i		row
	 * @int j		cell
	 **/
	protected void drawCell(Graphics g, int i, int j)
	{
		if((9*(i+1)+j+1) % 2 == 1)
			g.setColor(0x9DBDFF);
		else
			g.setColor(0xFFFFFF);
		g.fillRect(i*cellWidth+1, j*cellHeight+1, cellWidth, cellHeight);
		g.setColor(0x000000);
	}
	
	protected void drawCoin(Graphics g, int i, int j)
	{
		if(this.senku.getField(i,j)%10 == 2)
				g.setGrayScale(180);
		else
		{
			g.setColor(0xFFD427);
			g.fillArc(i*cellWidth+2, j*cellHeight+2, coinW, coinH,0, 360);
			g.setColor(0x000000);
		}
		g.drawArc(i*cellWidth+2, j*cellHeight+2, coinW, coinH,0, 360);
		
	}
	
	protected void drawSelected(Graphics g, int i, int j)
	{
		g.setColor(0xFF0000);
		g.drawRect(i*cellWidth+1, j*cellHeight+1, cellWidth-2, cellHeight-2);
	}
	
	protected void drawClock(Graphics g)
	{
		g.setGrayScale(0);
		g.drawString(clock.getElapsedTime() + " seg", w, 0, Graphics.TOP | Graphics.RIGHT);
	}
	
	public void restartGame()
	{
		this.initGame();
	}
	
	protected void initGame()
	{
		this.clock.start();
		this.senku.start();
		repaint();
	}
	
	public void initGame(String mode)
	{
		this.clock.start();
		this.senku.setMode(mode);
		this.senku.start();
		repaint();
	}
	
	public void keyReleased(int keyCode)
	{
		switch(getGameAction(keyCode))
		{
			case UP:
				cursorY = (cursorY == 0) ? 6 : (cursorY - 1) % 7;
				break;
			case DOWN:
				cursorY = (cursorY == 6) ? 0 : (cursorY + 1) % 7;
				break;
			case RIGHT:
				cursorX = (cursorX == 6) ? 0 : (cursorX + 1) % 7;
				break;
			case LEFT:
				cursorX = (cursorX == 0) ? 6 : (cursorX - 1) % 7;
				break;
			case GAME_A:
			case FIRE:
				if(!this.senku.selectCoin(cursorX, cursorY))
				{
					this.senku.moveCoinTo(cursorX, cursorY);
					if(this.senku.checkGameOver())
					{
						this.clock.stop();
						this.father.gameOver(this.senku.getMode(), this.senku.leftCoins());
					}
				}
				break;
		}
		repaint();
	}
	
}